var log_always_dual=false ;

/*
*   common function
*/
function SCUC_delay(ms) 
{
        var cur_d = new Date();
        var cur_ticks = cur_d.getTime();
        var ms_passed = 0;
        while(ms_passed < ms) {
            var d = new Date();  // Possible memory leak?
            var ticks = d.getTime();
            ms_passed = ticks - cur_ticks;
            // d = null;  // Prevent memory leak?
        }
}
    
/**
* https://gist.github.com/ptekchand/3447280
* Hack to work around "TypeError: Converting circular structure to JSON"
* which is seen when using JSON.stringify
* Intended to inspection/debugging purposes.
* Note: Will not display an Array in square brackets.
* Shows extra trailing comma before closing brace.
* @param obj
* @param [onlyProps] - Show only property names
* @param {String[]} [skipTypes=['function']] - array of types to trace only the type instead of value.
* @return {String}
*/
function shallowStringify(obj, onlyProps, skipTypes) {
var objType = typeof(obj);
if(['function', 'undefined'].indexOf(objType)>=0) {
return objType;
} else if(['string', 'number', 'boolean'].indexOf(objType)>=0) {
return obj; // will toString
}
// objType == 'object'
var res = '{';
for (p in obj) { // property in object
if(typeof(onlyProps)!=='undefined' && onlyProps) {
// Only show property names as values may show too much noise.
// After this you can trace more specific properties to debug
res += p+', ';
} else {
var valType = typeof(obj[p]);
if(typeof(skipTypes)=='undefined') {
skipTypes = ['function'];
}
if(skipTypes.indexOf(valType)>=0) {
res += p+': '+valType+', ';
} else {
res += p+': '+obj[p]+', ';
}
}
}
res += '}';
return res;
} 

/*

*   Debug Message
*/
/*
function GetStringFromArglist() {
    var msg = "" ;
    for (var i = 0; i < arguments.length; i++) 
    {
        msg += arguments[i] ;
        msg += " " ;
    }
    
    return msg ;
}

// print console log from argument list
function console_log_list()
{
console.log('console_log_list',arguments,arguments[0]) ;
    var msg=GetStringFromArglist(arguments[0]) ;
    console.log(msg) ;
}
*/

// redirect the argument list to node.js console.msg
// 1st argument must be io.connect() object
// 2nd argument must be module name
function node_console_log() 
{
    if( arguments.length<3 )
    {
        console.log('node_console_log arg err '+arguments.length) ;
        return ;
    }

    var io=arguments[0] ;
    if( null==io && undefined==io )
    {
        console.log('node_console_log io NULL') ;
        return ;
    }

    var msg = arguments[2] ;
    io.emit('nodeconsolelog',arguments[1]+' : '+msg) ;
}

// log to browser and node
function dual_log(msg,io)
{
    local_log(msg) ;

    if( !log_always_dual )
        server_log(msg,io) ;
}

// log to browser
function local_log(msg)
{
    console.log(msg) ;
    if( !log_always_dual ) {
        return ;
    }

    if( log_always_dual ) {
        // get temporal http io
        io = io.connect();

        if( !io )
            console.log('!io') ;
        else
            server_log(msg,io) ;
    }
}

// log to node
function server_log(msg,io)
{
    node_console_log(io,'HTML',msg) ;
}